package com.pureut.order.service.impl;

import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.pureut.order.domain.CustomerManagement;
import com.pureut.order.domain.SalesOrder;
import com.pureut.order.domain.SalesOrderDetail;
import com.pureut.order.dto.DetailViewDto;
import com.pureut.order.dto.SalesOrderDetailDto;
import com.pureut.order.dto.SalesOrderDetailViewDto;
import com.pureut.order.dto.SalesOrderDto;
import com.pureut.order.mapper.CustomerManagementMapper;
import com.pureut.order.mapper.SalesOrderDetailMapper;
import com.pureut.order.mapper.SalesOrderMapper;
import com.pureut.order.service.CustomerManagementService;
import com.pureut.order.service.SalesOrderDetailService;
import com.pureut.order.service.SalesOrderService;
import com.pureut.order.vo.GenerateInvoiceListVo;
import com.pureut.order.vo.GenerateInvoiceVo;
import com.pureut.order.vo.OrderReviewVo;
import com.pureut.order.vo.SalesOrderDetailVo;
import com.sale.common.core.constant.CacheNames;
import com.sale.common.core.domain.R;
import com.sale.common.core.exception.GlobalException;
import com.sale.common.dict.utils.DictUtils;
import com.sale.common.mybatis.core.page.PageQuery;
import com.sale.common.mybatis.core.page.TableDataInfo;
import com.sale.common.redis.utils.CacheUtils;
import com.sale.storage.api.RemotePickingSaleService;
import com.sale.storage.api.vo.PickingSaleRelationResultVo;
import com.sale.storage.api.vo.PickingSaleResultVo;
import com.sale.system.api.RemoteReviewService;
import com.sale.system.api.RemoteStaffManagementService;
import com.sale.system.api.RemoteUnitService;
import com.sale.system.api.RemoteUserService;
import com.sale.system.api.domain.SysAuxiliary;
import com.sale.system.api.domain.SysDictData;
import com.sale.system.api.domain.dto.SysStaffManagementDto;
import com.sale.system.api.domain.vo.SysAuditHistoryVo;
import lombok.RequiredArgsConstructor;
import org.apache.dubbo.config.annotation.DubboReference;
import org.hibernate.validator.internal.util.stereotypes.Lazy;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static java.lang.Double.doubleToLongBits;

/***
 * 销售订单明细实现层
 * Author:C
 * Date:2022/12/01 10:56
 * @DESC
 */
@Service
@RequiredArgsConstructor
public class SalesOrderDetailServiceImpl implements SalesOrderDetailService {


    private final SalesOrderDetailMapper salesOrderDetailMapper;

    private final CustomerManagementMapper customerManagementMapper;

    private final SalesOrderMapper salesOrderMapper;

    @DubboReference
    private final RemoteReviewService remoteReviewService;

    @DubboReference
    RemoteStaffManagementService remoteStaffManagementService;

    @DubboReference
    RemoteUnitService remoteUnitService;

    @DubboReference
    RemoteUserService remoteUserService;

    @DubboReference
    RemotePickingSaleService remotePickingSaleService;

    /**
     * 获取销售订单明细列表
     *
     * @param id
     * @return
     */
    @Override
    public TableDataInfo<SalesOrderDetailDto> getList(Long id, PageQuery pageQuery) {
        //状态
        List<SysDictData> statusArray = CacheUtils.get(CacheNames.SYS_DICT, "sales_order_detail_status");
        Map<String, String> statusMap = statusArray.stream().collect(Collectors.toMap(SysDictData::getDictValue, SysDictData::getDictLabel));

        //获取明细列表
        Page<SalesOrderDetailDto> detailList = salesOrderDetailMapper.getDetailList(pageQuery.build(), id);
        List<SalesOrderDetailDto> records = detailList.getRecords();

        for (SalesOrderDetailDto entity : records) {
            //物料类别
            if (entity.getMaterialCategory() == 1) {
                entity.setCodingRules("原料");
            } else {
                entity.setCodingRules("成品");
            }
            //辅助属性
            List<SysAuxiliary> statsArray = CacheUtils.get(CacheNames.SYS_GINSENG + "_" + entity.getTenantId(), String.valueOf(entity.getMaterialId()));
            entity.setAuxiliaryAttribute(statsArray);
            //状态
            entity.setOrderDetailStatusDict(statusMap.get(entity.getOrderDetailStatus()));
            //单位
            entity.setUnitDict(remoteUnitService.getUnitDataByCode(Long.parseLong(entity.getMaterialUnit())).getData().getUnitName());
        }
        return TableDataInfo.build(detailList);
    }

    /**
     * 查看明细
     *
     * @param id
     * @return
     */
    @Override
    public SalesOrderDetailDto getView(Long id) {
        //获取明细信息
//        SalesOrderDetail salesOrderDetail = getById(id);
        SalesOrderDetailDto viewById = salesOrderDetailMapper.getViewById(id);
        //获取订单信息
        SalesOrder salesOrder = salesOrderMapper.selectById(viewById.getSalesOrderId());
        SalesOrderDetailDto salesOrderDetailDto = new SalesOrderDetailDto();
        BeanUtils.copyProperties(viewById, salesOrderDetailDto);
        //销售人员
        salesOrderDetailDto.setAttributor(salesOrder.getAttributor());

        if (salesOrder.getAttributor() != null) {
            //销售人员
            Long staffId = Long.valueOf(salesOrder.getAttributor());
            salesOrderDetailDto.setAttributorDict(remoteStaffManagementService.getInfo(staffId).getData().getStaffName());
        }
        //开单日期
        salesOrderDetailDto.setBillingDate(salesOrder.getBillingDate());
        List<SalesOrderDetailViewDto> salesOrderDetailViewDtoList = new ArrayList<>();
        SalesOrderDetailViewDto salesOrderDetailViewDto = new SalesOrderDetailViewDto();
        salesOrderDetailDto.setId(salesOrder.getId());
        //获取客户信息
        CustomerManagement byId = customerManagementMapper.selectOne(new QueryWrapper<CustomerManagement>().lambda().eq(CustomerManagement::getCustomerNum, salesOrder.getCustomerNum()));
        salesOrderDetailDto.setCustomerName(byId.getCustomerName());
        salesOrderDetailDto.setCustomerNum(salesOrder.getCustomerNum());

        salesOrderDetailDto.setOrderType(String.valueOf(salesOrder.getOrderType()));
        salesOrderDetailDto.setOrderPriority(String.valueOf(salesOrder.getOrderPriority()));
        //备注
        salesOrderDetailDto.setRemark(salesOrder.getRemark());
        //文件
        salesOrderDetailDto.setContractUrl(salesOrder.getContractUrl());
        //退回原因
        salesOrderDetailDto.setBackReason(salesOrder.getBackReason());
        //终止原因
        salesOrderDetailDto.setStopReason(salesOrder.getStopReason());
        //销售订单号
        salesOrderDetailDto.setSalesOrderNum(salesOrder.getSalesOrderNum());
        //销售合同号
        salesOrderDetailDto.setSalesContractNum(salesOrder.getSalesContractNum());

        salesOrderDetailViewDto.setMaterialName(viewById.getMaterialName());
        salesOrderDetailViewDto.setMaterialCode(viewById.getMaterialCode());
        salesOrderDetailViewDto.setMaterialSpec(viewById.getMaterialSpec());
        salesOrderDetailViewDto.setMaterialPlace(viewById.getMaterialPlace());
        salesOrderDetailViewDto.setId(viewById.getId());
        salesOrderDetailViewDto.setWidthCloth(viewById.getWidthCloth());
        salesOrderDetailViewDto.setDeviationValue(viewById.getDeviationValue());
        salesOrderDetailViewDto.setDeliveryDate(viewById.getDeliveryDate());
        salesOrderDetailViewDto.setRollDiameter(viewById.getRollDiameter());
        salesOrderDetailViewDto.setThickness(viewById.getThickness());
        salesOrderDetailViewDto.setUnitPrice(viewById.getUnitPrice());
        salesOrderDetailViewDto.setPlanWeight(viewById.getPlanWeight());
        salesOrderDetailViewDto.setQualityStandard(String.valueOf(viewById.getQualityStandard()));
        salesOrderDetailViewDto.setNumberRolls(String.valueOf(viewById.getNumberRolls()));
        salesOrderDetailViewDto.setDeviation(String.valueOf(viewById.getDeviation()));
        salesOrderDetailViewDto.setPacking(String.valueOf(viewById.getPacking()));
        salesOrderDetailViewDto.setOrderDetailStatus(String.valueOf(viewById.getOrderDetailStatus()));
        //已发货重量
        salesOrderDetailViewDto.setProducedWeight(viewById.getProducedWeight());
        //已生产重量
        salesOrderDetailViewDto.setShippingWeight(viewById.getShippingWeight());
        //单位
        salesOrderDetailViewDto.setMaterialUnit(viewById.getMaterialUnit());
        //金额
        salesOrderDetailViewDto.setDetailPrice(viewById.getDetailPrice());
        //数量
        salesOrderDetailViewDto.setSocketNumber(viewById.getSocketNumber());
        //类别
        if (viewById.getMaterialCategory() == 1) {
            salesOrderDetailViewDto.setMaterialCategoryDict("原料");
        } else {
            salesOrderDetailViewDto.setMaterialCategoryDict("成品");
        }

        //单位
        salesOrderDetailViewDto.setUnitDict(remoteUnitService.getUnitDataByCode(Long.parseLong(viewById.getMaterialUnit())).getData().getUnitName());
        //辅助属性
        List<SysAuxiliary> statsArray = CacheUtils.get(CacheNames.SYS_GINSENG + "_" + viewById.getTenantId(), String.valueOf(viewById.getMaterialId()));
        salesOrderDetailViewDto.setAuxiliaryAttribute(statsArray);

        salesOrderDetailViewDtoList.add(salesOrderDetailViewDto);
        salesOrderDetailDto.setSalesOrderDetailDtoList(salesOrderDetailViewDtoList);
        return salesOrderDetailDto;
    }

    /**
     * 修改
     *
     * @param salesOrderDetailVo
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateSalesOrderDetail(SalesOrderDetailVo salesOrderDetailVo) {
        SalesOrderDetail salesOrderDetail = salesOrderDetailMapper.selectById(salesOrderDetailVo.getId());
        if (salesOrderDetail.getOrderDetailStatus() != 2 && salesOrderDetail.getOrderDetailStatus() != 7) {
            throw new GlobalException("只能修改未通过或者待提交的明细数据");
        }
        //获取订单数据
        SalesOrder salesOrder = salesOrderMapper.selectOne(new QueryWrapper<SalesOrder>().lambda().eq(SalesOrder::getId, salesOrderDetail.getSalesOrderId()));
        if (salesOrderDetail.getOrderDetailStatus() == 2) {
            salesOrderDetail.setMaterialUnit(salesOrderDetailVo.getMaterialUnit())
                .setSocketNumber(Integer.parseInt(salesOrderDetailVo.getSocketNumber()))
                .setUnitPrice(salesOrderDetailVo.getUnitPrice())
                .setDeliveryDate(salesOrderDetailVo.getDeliveryDate());

            //调用审核
            SysAuditHistoryVo sysAuditHistoryVo = new SysAuditHistoryVo();
            String perms = "order:saleOrder:examine";
            String auditDoc = salesOrder.getSalesOrderNum() + salesOrderDetail.getId();
            sysAuditHistoryVo.setAuditDoc(auditDoc);
            sysAuditHistoryVo.setPerms(perms);
            int i = remoteReviewService.editHistory(sysAuditHistoryVo);

            if (i > 0) {
                salesOrderDetail.setOrderDetailStatus(1);
                return salesOrderDetailMapper.updateById(salesOrderDetail) > 0;
            } else {
                return false;
            }
        } else {
            salesOrderDetail.setMaterialUnit(salesOrderDetailVo.getMaterialUnit())
                .setSocketNumber(Integer.parseInt(salesOrderDetailVo.getSocketNumber()))
                .setUnitPrice(salesOrderDetailVo.getUnitPrice())
                .setDeliveryDate(salesOrderDetailVo.getDeliveryDate());
            return salesOrderDetailMapper.updateById(salesOrderDetail) > 0;
        }
    }

    /**
     * 根据订单id和物料编码查询销售明细
     *
     * @param salesOrderId, String materialCode
     * @return
     */
    @Override
    public DetailViewDto getDetailById(Long salesOrderId, String materialCode) {

        DetailViewDto viewDto = new DetailViewDto();
        SalesOrderDetail one = salesOrderDetailMapper.selectOne(new QueryWrapper<SalesOrderDetail>().lambda().eq(SalesOrderDetail::getSalesOrderId, salesOrderId).eq(SalesOrderDetail::getMaterialCode, materialCode));
        if (one != null) {
            viewDto.setWidthCloth(one.getWidthCloth());
            viewDto.setThickness(one.getThickness());
            viewDto.setNumberRolls(one.getNumberRolls());
            viewDto.setRollDiameter(one.getRollDiameter());
            //获取包装字典数据
            List<SysDictData> packArray = DictUtils.getDictCache("sale_order_packing");
            Map<String, String> packMap = packArray.stream().collect(Collectors.toMap(SysDictData::getDictValue, SysDictData::getDictLabel));
            viewDto.setPacking(one.getPacking());
            String s = String.valueOf(one.getPacking());
            viewDto.setPackingDict(packMap.get(s));
            SalesOrder salesOrder = salesOrderMapper.selectById(salesOrderId);
            viewDto.setRemark(salesOrder.getRemark());
            viewDto.setContractUrl(salesOrder.getContractUrl());
        } else {
            throw new GlobalException("查询的数据不存在");
        }
        return viewDto;
    }

    /**
     * 生成发货单
     *
     * @param generateInvoiceVo
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean generateInvoice(GenerateInvoiceVo generateInvoiceVo) throws Exception {

        //获取明细信息
        SalesOrderDetail byId = salesOrderDetailMapper.selectById(generateInvoiceVo.getList().get(0).getId());
        if (byId.getOrderDetailStatus() == 4) {
            //获取订单信息
            SalesOrder salesOrder = salesOrderMapper.selectById(byId.getSalesOrderId());

            PickingSaleResultVo pickingSaleVo1 = new PickingSaleResultVo();

            pickingSaleVo1.setTransceiverType(1);
            pickingSaleVo1.setDateDelivery(new Date());
            pickingSaleVo1.setCustomerNum(generateInvoiceVo.getCustomerCode());

            List<GenerateInvoiceListVo> list = generateInvoiceVo.getList();

            //校验列表中填写的计划发货量不能大于明细中的数量
            for (GenerateInvoiceListVo entity : list) {
                double plannedWeight = entity.getPlannedWeight();
                double socketNumber = Double.parseDouble(String.valueOf(byId.getSocketNumber()));
                if (plannedWeight > socketNumber) {
                    throw new GlobalException("计划发货量不能大于数量");
                }
            }


            List<PickingSaleRelationResultVo> pickingSaleRelationVoList = new ArrayList<>();
            for (GenerateInvoiceListVo entity : list) {
                PickingSaleRelationResultVo pickingSaleRelationVo = new PickingSaleRelationResultVo();

                pickingSaleRelationVo.setConnectionId(salesOrder.getSalesOrderNum());
                pickingSaleRelationVo.setMaterialCode(entity.getMaterialCode());
                pickingSaleRelationVo.setMaterialId(entity.getMaterialId());
                pickingSaleRelationVo.setPlannedWeight(entity.getPlannedWeight());
                pickingSaleRelationVo.setMaterialUnit(Long.parseLong(byId.getMaterialUnit()));
                pickingSaleRelationVo.setUnitPrice(entity.getUnitPrice());
                pickingSaleRelationVoList.add(pickingSaleRelationVo);
            }

            pickingSaleVo1.setList(pickingSaleRelationVoList);
            boolean b = remotePickingSaleService.addSaleOrder(pickingSaleVo1);

            if (b) {
//                byId.setShippingWeight(String.valueOf(list.get(0).getPlannedWeight()));
                return salesOrderDetailMapper.updateById(byId) > 0;
            }
            return b;
        } else {
            throw new GlobalException("只能操作“进行中”的数据");
        }
    }

    /**
     * 根据物料编码获取销售订单
     *
     * @param materialCode
     * @return
     */
    @Override
    public List<SalesOrderDto> getOrderByMaterialCode(String materialCode) {

        return salesOrderDetailMapper.getOrderDocmentList(materialCode);
    }
}
